<?php
/**
 * Created by ephp
 * User: 22071
 * Date: 2019/6/15
 * Email: <zhendongdong@foxmail.com>
 */

namespace paper;


use paper\pdo\Query;
use paper\support\Model;

class Relation
{
    const BELONG_TO = 'paper\\relation\\BelongTo';
    const HAS_ONE = 'paper\\relation\\HasOne';
    const HAS_MANY = 'paper\\relation\\HasMany';
    /**
     * @var Query
     */
    protected $query = null;

    public $localKey = '';
    public $foreignKey = '';
    public $where = [];
    public $model = null;
    /**
     * @var Model $relationModel
     */
    public $relationModel = null;

    /**
     * Relation constructor.
     * @param Model $model
     * @param string $relationModel
     * @param null $localKey
     * @param null $foreignKey
     * @throws \Exception
     */
    private function __construct(Model $model, string $relationModel, $localKey = null, $foreignKey = null)
    {
        /**
         * @var Model $rModel
         */
        $with = null;
        if ($index = strpos($relationModel, '.')) {
            [$relationModel, $with] = explode(".", $relationModel, 2);
        }
        $rModel              = new $relationModel();
        $this->relationModel = $rModel;
        $this->model         = $model;
        //设置外键和关联模型主键
        $this->getRelationKey($localKey, $foreignKey);
        if ($with) {
            $this->query = $rModel::query()->with($with);
        } else {
            $this->query = $rModel::query();
        }
    }

    public function getRelationKey($localKey, $foreignKey)
    {
        $this->localKey   = $localKey ?: $this->relationModel->tabName() . '_id';
        $this->foreignKey = $foreignKey ?: $this->relationModel->getPk();
    }

    public function where($where)
    {
        $this->where[] = $where;
        return $this;
    }

    protected function constraint()
    {
        $v = $this->model->getData($this->localKey);
        return $this->query->where([$this->foreignKey => $v])->where($this->where);
    }

    public static function create($type, Model $model, string $relationModel, $localKey = null, $foreignKey = null)
    {
        return new $type($model, $relationModel, $localKey, $foreignKey);
    }

    public function query()
    {
        return $this->constraint();
    }

    public function prepareRelation(&$result)
    {
        return [];
    }


    public function getData()
    {
        return [];
    }

    /*
     * @return Query
     */
    public function __call($name, $arguments)
    {
        return $this->constraint()->$name($arguments);
    }

}